#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <wait.h>
#define MAX_SIZE 1024
void sig_handler(int signo)
{
  printf("父进程退出\n");
  exit(0);
}

int main()
{
  struct msgbuf
  {
    long mtype;
    char mtext[MAX_SIZE];
  };

  int msgid;
  key_t key;
  pid_t pid;
  pid = fork();
  if (pid > 0)
  {
    struct msgbuf msg;
    key = ftok("./mq1", 1);
    if (key < 0)
    {
      perror("ftok");
      exit(1);
    }
    msgid = msgget(key, 0666 | IPC_CREAT);
    if (msgid < 0)
    {
      perror("msgget");
      exit(1);
    }
    // 注册信号捕捉
    signal(SIGUSR1, sig_handler);

    while (1)
    {
      write(1, "请输入要发送的消息:\n", sizeof("请输入要发送的消息:\n"));
      fgets(msg.mtext, MAX_SIZE, stdin);
      msg.mtype = 1;
      msgsnd(msgid, &msg, MAX_SIZE, 0);
      printf("消息发送成功.\n");
      if (strcmp(msg.mtext, "exit\n") == 0)
      {
        kill(pid, SIGQUIT);
        waitpid(pid, NULL, 0);
        printf("父进程退出\n");
        exit(0);
      }
    }
  }
  else if (pid == 0)
  {
    struct msgbuf msg;
    key = ftok("./mq2", 2);
    msgid = msgget(key, 0666 | IPC_CREAT);
    if (msgid < 0)
    {
      perror("msgget");
      exit(1);
    }
    while (1)
    {
      msgrcv(msgid, &msg, MAX_SIZE, 2, 0);
      printf("收到消息:%s\n", msg.mtext);
      if (strcmp(msg.mtext, "exit\n") == 0)
      {
        kill(getppid(), SIGUSR1);
        printf("子进程退出\n");
        exit(0);
      }
    }
  }
  else
  {
    perror("fork");
    exit(1);
  }
}